package com.oj.config;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.oj.interceptor.AutoLoginInterceptor;
import com.oj.interceptor.AdminInterceptor;
import com.oj.interceptor.ContestInterceptor;
import com.oj.interceptor.LoginInterceptor;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.TimeZone;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    // 重写的WebMvcConfigurer在添加拦截器之前用@bean注解将拦截器注入工厂，接着添加拦截器才不会出现mapper是null的情况
    @Bean
    public LoginInterceptor loginInterceptor(){
        return new LoginInterceptor();
    }

    @Bean
    public AutoLoginInterceptor autoLoginInterceptor(){
        return new AutoLoginInterceptor();
    }

    @Bean
    public AdminInterceptor adminInterceptor(){
        return new AdminInterceptor();
    }

    @Bean
    public ContestInterceptor contestInterceptor(){
        return new ContestInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 自动登录拦截器
        registry.addInterceptor(autoLoginInterceptor())
                .addPathPatterns(
                        "/",
                        "/ide",
                        "/profile/**",
                        "/settings/**",
                        "/problemset/**",
                        "/problem/**",
                        "/contests/**",
                        "/contest/**",
                        "/mails/**",
                        "/topics/**",
                        "/topic/**",
                        "/tags/**",
                        "/admin/**")
                .excludePathPatterns(
                        "/login",
                        "/logout",
                        "/api/**",
                        "/topic/postmessage");

        // 检查登录状态拦截器
        registry.addInterceptor(loginInterceptor()).
                addPathPatterns(
                        "/settings",
                        "/topic/new",
                        "/topic/postmessage",
                        "/contest/**/register",
                        "/contest/**/unregister",
                        "/mails/**",
                        "/admin/**",
                        "/contest/**/problem/**");

        // 检查ADMIN状态拦截器
        registry.addInterceptor(adminInterceptor()).
                addPathPatterns(
                        "/admin/**",
                        "/api/admin/**");

        // contest拦截器
        registry.addInterceptor(contestInterceptor()).
                addPathPatterns(
                        "/contest/**/")
                .excludePathPatterns(
                        "/contest/**/standings/**",
                        "/contest/**/registrants/**",
                        "/contest/**/unregister",
                        "/contest/**/register");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        ApplicationHome h = new ApplicationHome(getClass());
        if (h == null || h.getSource() == null || h.getSource().getParentFile() == null) {
            return;
        }
        String dirPath = h.getSource().getParentFile().toString()+"/upload/";
        registry.addResourceHandler("/upload/**").addResourceLocations("file:"+dirPath);

        String dirPath1 = h.getSource().getParentFile().toString()+"/data/";
        registry.addResourceHandler("/data/**").addResourceLocations("file:"+dirPath1);
    }

    @Bean
    public HttpMessageConverter responseBodyConverter(){
        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        return converter;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(responseBodyConverter());
    }
}
